package com.zhuangjie.rider.ws.listener;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhuangjie.mvc.helper.GeoHelper.GeoCoordinates;
import com.zhuangjie.mvc.ws.annotation.*;
import com.zhuangjie.mvc.ws.entity.WSMessageSessionInfo;
import com.zhuangjie.redis.entity.RedisGeo;
import com.zhuangjie.redis.helper.RedisGeoHelper;
import com.zhuangjie.rider.constant.RiderGeoInfoConstant;
import com.zhuangjie.rider.entity.DeliveryOrder;
import com.zhuangjie.rider.enums.AssignState;
import com.zhuangjie.rider.lock.DeliveryOrderLock;
import com.zhuangjie.rider.service.DeliveryOrderService;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.CompletableFuture;


@WSListener(ws = "/rider")
public class RiderWSListener {
    @Autowired
    private RedisGeoHelper redisGeoHelper;

    @Autowired
    private DeliveryOrderService deliveryOrderService;

    @Autowired
    private Redisson redisson;

    /**
     * 接收到更新骑手的位置消息
     *
     * @param geo         geo
     * @param sessionInfo 会话信息
     */
    @OnMessage("/put-geo")
    private void putRiderGeo(@MessageBody GeoCoordinates geo, WSMessageSessionInfo sessionInfo) {
        RedisGeo redisGeo = new RedisGeo();
        String riderId = sessionInfo.getServiceId();
        redisGeo.setKey(RiderGeoInfoConstant.RIDER_GEO_INFO_KEY);
        redisGeo.setLongitude(geo.getLongitude());
        redisGeo.setLatitude(geo.getLatitude());
        redisGeo.setMember(riderId);
        redisGeoHelper.put(redisGeo);

        // 将骑手位置，通知骑手持有但未完成的订单对应的用户
        CompletableFuture.runAsync(()->deliveryOrderService.notifyRiderLocation(Long.valueOf(riderId), geo));
    }
    @OnMessage("/reject-delivery-order/{deliveryOrderId}")
    private void rejectDeliveryOrder(@MessagePathVariable("deliveryOrderId") Long deliveryOrderId , WSMessageSessionInfo sessionInfo) {
        RLock lock = redisson.getLock(DeliveryOrderLock.getDeliveryOrderOperationLock(deliveryOrderId));
        lock.lock();
        try {
            String riderId = sessionInfo.getServiceId();
            LambdaUpdateWrapper<DeliveryOrder> updateAssignToEmptyWrapper = Wrappers.lambdaUpdate(DeliveryOrder.class)
                    .eq(DeliveryOrder::getId, deliveryOrderId)
                    .eq(DeliveryOrder::getAssignRiderId, riderId)
                    .set(DeliveryOrder::getAssignRiderId, AssignState.UNASSIGNED);
            deliveryOrderService.update(updateAssignToEmptyWrapper);
        }finally {
            lock.unlock();
        }
        // 不用回复，就算失败也没事（会有自动超时）
    }
    @OnOpen
    public void onOpen(WSMessageSessionInfo sessionInfo) {
        System.out.println("WS onOpen");
    }

    /**
     * 当客户端断开连接时移除骑手的坐标信息
     * @param sessionInfo
     */
    @OnClose
    @OnError
    public void onDisconnected(WSMessageSessionInfo sessionInfo) {
        redisGeoHelper.remove(RiderGeoInfoConstant.RIDER_GEO_INFO_KEY, sessionInfo.getServiceId());
    }

}
